package com.ginger.sms;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/**
 * 短信发送实例
 * java项目需要jdk1.7及以上版本,需要引用httpClient4.2.4及以上版本
 * 该实例为maven项目,引用httpClient4.2.4可使用pom.xml直接引用
 *
 * @author txy
 * @date 2018/01/30.
 */
public class SmsTest {
    /**
     * 腾讯云交易id
     * 必填项
     */
    private static String SECRET_ID = "SECRET_ID";
    /**
     * 腾讯云交易key
     * 必填项
     */
    private static String SECRET_KEY = "SECRET_KEY";


    public static void main(String[] args) throws Exception {
        /**
         * api发送接口
         * 必填项
         */
        String host = "http://service-4xrmju6b-1255399658.ap-beijing.apigateway.myqcloud.com";
        String path = "/release/dxsms";
        /**
         * 您需要发送手机号
         * 必填项
         */
        String mobile = "15727395495";
        /**
         * 模板id,联系客服申请通过的模板,
         * 例:TP1801042是已申请好的模板:您的验证码是#code#
         * 必填项
         */
        String tpl_id = "TP1801042";
        /**
         * 与模板中对应的变量,有多个变量则使用","隔开
         * 例:短信模板为“您的电话#telephone#成功缴费#money#元，如未到账可直接拨打客服电话#phone#”，
         * 则param="telephone:13288888888,money:100,phone:400-888888"
         *
         */
        String SMSCode = "953458";
        String param = "code:"+SMSCode;
        String url = host + path + "?mobile=" + mobile + "&tpl_id=" + tpl_id + "&param=" + param;
        /**
         * httpClient4.2.4及以上版本
         */
        HttpClient httpClient = new DefaultHttpClient();
        // get method
        HttpGet httpGet = new HttpGet(url);
        Date date = new Date();
        httpGet.setHeader("Date", gmtTIME(date));
        String timeStr = "date: " + gmtTIME(date);
        String sign = hmacSHA1Encrypt(timeStr, SECRET_KEY);
        String authStr = "hmac id=\"" + SECRET_ID + "\",algorithm=\"hmac-sha1\",headers=\"date\", signature=\"" + sign + "\"";
        httpGet.addHeader("Authorization", authStr);
        //response
        HttpResponse response = null;
        try {
            response = httpClient.execute(httpGet);
        } catch (Exception e) {
        }
        //get response into String
        String temp = "";
        try {
            HttpEntity entity = response.getEntity();

            temp = EntityUtils.toString(entity, "UTF-8");
            ObjectMapper mapper = new ObjectMapper();
            SMSObject sMSObject = mapper.readValue(temp, SMSObject.class);
            //输出返回值
             System.out.println(temp);
            
            System.out.println(sMSObject);
        } catch (Exception e) {
        }


    }

    /**
     * HmacSHA1加密
     *
     * @param encryptText 加密字符串
     * @param encryptKey  加密key
     * @return
     * @throws Exception
     */
    private static String hmacSHA1Encrypt(String encryptText, String encryptKey) throws Exception {
        byte[] data = encryptKey.getBytes("UTF-8");
        //根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
        SecretKey secretKey = new SecretKeySpec(data, "HmacSHA1");
        //生成一个指定 Mac 算法 的 Mac 对象
        Mac mac = Mac.getInstance("HmacSHA1");
        //用给定密钥初始化 Mac 对象
        mac.init(secretKey);

        byte[] text = encryptText.getBytes("UTF-8");
        //完成 Mac 操作,base64编码
        String sign = Base64.encodeBase64String(mac.doFinal(text));
        return sign;
    }


    /**
     * 获得格林威治时间
     *
     * @param date 时间
     * @return
     */
    private static String gmtTIME(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
        // 设置时区为GMT
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
        String time = sdf.format(date.getTime());
        return time;
    }

}
